
package com.be.beadmin.product.impl;


import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.design.dto.input.ProcessDto;
import com.be.beadmin.product.dto.input.PlantCapacityBaseDto;
import com.be.beadmin.product.dto.output.BaseCapacity;
import com.be.beadmin.product.dto.output.PlantCapacityBaseEx;
import com.be.beadmin.product.entity.PlantCapacityBase;
import com.be.beadmin.product.entity.PlantCapacityBase_;
import com.be.beadmin.product.mapper.PlantCapacityBaseMapper;
import com.be.beadmin.product.mapper.PlantCapacityBaseMapperEx;
import com.be.beadmin.product.repository.PlantCapacityBaseRepository;
import com.be.beadmin.product.service.PlantCapacityBaseService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @description 服务实现
* @author ljh
* @date 2023-03-26
**/
@Service
@RequiredArgsConstructor
public class PlantCapacityBaseServiceImpl implements PlantCapacityBaseService {

    @Autowired
    private  PlantCapacityBaseRepository plantCapacityBaseRepository;
    @Autowired
    private  PlantCapacityBaseMapper plantCapacityBaseMapper;
    @Autowired
    private  PlantCapacityBaseMapperEx plantCapacityBaseExMapper;

    @Override
    public Page<PlantCapacityBaseEx> getPlantCapacityBaseByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<PlantCapacityBase> page = plantCapacityBaseRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilderNew.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PlantCapacityBase_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PlantCapacityBase_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<PlantCapacityBaseEx> page1 = page.map(plantCapacityBaseExMapper::toEntity);
            return page1;

    }

    @Override
    public void addPlantCapacityBase(PlantCapacityBaseDto plantCapacityBaseDto) {
            PlantCapacityBase result = plantCapacityBaseRepository.findPlantCapacityBaseByIdAndDelete(plantCapacityBaseDto.getId(), 0);
            if(ObjectUtil.isNotEmpty(result)) {
                throw new BeadminException("PlantCapacityBase不存在,请重新查询");
            }
//        某车间各工序正常产能=某车间工序每个班次人数*每天正常工作时长*班次*工作效率。
//        某车间各工序加班后总产能=某车间工序每个班次人数*（每天正常工作时长+每天加班时长）*班次*工作效率。
            String processCode = plantCapacityBaseDto.getProcessCode();
            if(processCode==null||processCode.equals(""))  throw new BeadminException("需要选择工序");
            PlantCapacityBase plantCapacityBase = plantCapacityBaseRepository.findPlantCapacityBaseByProcessCodeAndDelete(processCode,0);
            if (plantCapacityBase!=null){
                throw new BeadminException("该工序已有产能数据，不能重复添加");
            }

            int workerQTY = plantCapacityBaseDto.getWorkerQty();
            int shiftQty = plantCapacityBaseDto.getShiftQty();
            float efficiency = plantCapacityBaseDto.getEfficiency();
            float normalTime = plantCapacityBaseDto.getNormalTime();
            float overtime = plantCapacityBaseDto.getOverTime();

            if(workerQTY<0) throw new BeadminException("人数需为正整数");
            if(shiftQty<0) throw new BeadminException("班次数需为正整数");
            if(efficiency<0||efficiency>100) throw new BeadminException("工作效率的范围为0~100");
            if(normalTime<0) throw new BeadminException("每天工作时长需为正数");
            if(overtime<0) throw new BeadminException("加班时长需为正数");

            float normalCapacity = workerQTY * normalTime * shiftQty * efficiency/100;
            float overtimeCapacity = workerQTY * overtime * shiftQty * efficiency/100;
            float totalCapacity = normalCapacity + overtimeCapacity;
            plantCapacityBaseDto.setNormalCapacity(normalCapacity);
            plantCapacityBaseDto.setOvertimeCapacity(overtimeCapacity);
            plantCapacityBaseDto.setTotalCapacity(totalCapacity);

            plantCapacityBase = plantCapacityBaseMapper.toEntity(plantCapacityBaseDto);
            plantCapacityBaseRepository.save(plantCapacityBase);
    }

    @Override
    public void updatePlantCapacityBase(PlantCapacityBaseDto plantCapacityBaseDto) {
            PlantCapacityBase plantCapacityBase = plantCapacityBaseRepository.findPlantCapacityBaseById(plantCapacityBaseDto.getId());

            int workerQTY = plantCapacityBaseDto.getWorkerQty();
            int shiftQty = plantCapacityBaseDto.getShiftQty();
            float efficiency = plantCapacityBaseDto.getEfficiency();
            float normalTime = plantCapacityBaseDto.getNormalTime();
            float overtime = plantCapacityBaseDto.getOverTime();

            float normalCapacity = workerQTY * normalTime * shiftQty * efficiency/100;
            float overtimeCapacity = workerQTY * overtime * shiftQty * efficiency/100;
            float totalCapacity = normalCapacity + overtimeCapacity;
            plantCapacityBaseDto.setNormalCapacity(normalCapacity);
            plantCapacityBaseDto.setOvertimeCapacity(overtimeCapacity);
            plantCapacityBaseDto.setTotalCapacity(totalCapacity);

            plantCapacityBase = plantCapacityBaseMapper.toEntity(plantCapacityBaseDto);
            plantCapacityBaseRepository.save(plantCapacityBase);
    }


    @Override
    public void delPlantCapacityBase(String id) {
        PlantCapacityBase plantCapacityBase = plantCapacityBaseRepository.findPlantCapacityBaseById(id);
        plantCapacityBase.setDelete(1);
        plantCapacityBaseRepository.save(plantCapacityBase);
    }

    @Override
    public void delPlantCapacityBases (List<String> ids) { }

    @Override
    public BaseCapacity getPlantCapacityBase(ProcessDto processDto) {
        if(processDto == null){
            BaseCapacity baseCapacity = new BaseCapacity();
            float normalCapacity = 0;
            float overtimeCapacity=0;
            float totalCapacity=0;
            List<PlantCapacityBase> plantCapacityBaseList = plantCapacityBaseRepository.findAllByDelete(0);
            for(PlantCapacityBase plantCapacityBase :plantCapacityBaseList){
                normalCapacity = normalCapacity + plantCapacityBase.getNormalCapacity();
                overtimeCapacity = overtimeCapacity + plantCapacityBase.getOvertimeCapacity();
                totalCapacity = totalCapacity + plantCapacityBase.getTotalCapacity();
            }
            baseCapacity.setNormalCapacity(normalCapacity);
            baseCapacity.setOvertimeCapacity(overtimeCapacity);
            baseCapacity.setTotalCapacity(totalCapacity);
            return baseCapacity;
        }else{
            BaseCapacity baseCapacity = new BaseCapacity();
            PlantCapacityBase plantCapacityBase = plantCapacityBaseRepository.findPlantCapacityBaseByProcessCodeAndDelete(processDto.getProcessCode(),0);
            if(plantCapacityBase==null){
                baseCapacity.setNormalCapacity((float) 0);
                baseCapacity.setOvertimeCapacity((float) 0);
                baseCapacity.setTotalCapacity((float) 0);
            }else{
                baseCapacity.setNormalCapacity(plantCapacityBase.getNormalCapacity());
                baseCapacity.setOvertimeCapacity(plantCapacityBase.getOvertimeCapacity());
                baseCapacity.setTotalCapacity(plantCapacityBase.getTotalCapacity());
            }
            return baseCapacity;
        }
    }

    @Override
    public PlantCapacityBase getProcessByProcessCodeAndDelete(String processCode, Integer delete) {
        PlantCapacityBase plantCapacityBase = plantCapacityBaseRepository.findPlantCapacityBaseByProcessCodeAndDelete(processCode,delete);
        return plantCapacityBase;
    }

}